import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:flutter_deer/util/log/text_channel_system.dart';
import 'package:rxdart/rxdart.dart';

class SocketClient {
  SocketClient({
    required String host,
    required int port,
    required int indexMdc,
    Duration reconnectInterval = const Duration(seconds: 5),
  })  : _host = host,
        _port = port,
        _indexMdc = indexMdc,
        _reconnectInterval = reconnectInterval;
  Socket? _socket;
  final String _host;
  final int _port;
  final int _indexMdc;
  final Duration _reconnectInterval;
  Timer? _reconnectTimer;
  bool _isReconnecting = false;

  /// 数据接收流
  final dataStream = BehaviorSubject<String>();
  /// 连接状态流
  final connectionStateStream = BehaviorSubject<bool>();

  StreamSubscription<List<int>>? _socketSubscription;

  final logger = TextChannelSystem.instance;

  /// 连接到服务器
  Future<void> connect() async {
    try {
      logger.createChannel(getUniqueKey());
      logger.addLineToChannel(getUniqueKey(), 'Connected to server...');
      _socket = await Socket.connect(_host, _port, timeout: const Duration(seconds: 4));
      logger.addLineToChannel(getUniqueKey(), 'Connected Success!');
      connectionStateStream.add(true);
      _isReconnecting = false;
      _reconnectTimer?.cancel();
      _reconnectTimer = null;
      _startListening();
    } catch (e) {
      logger.addLineToChannel(getUniqueKey(), 'Connection failed: _isReconnecting=$_isReconnecting  \n$e');
      _startReconnecting();
    }
  }

  /// 开始监听服务器发送的数据
  void _startListening() {
    _socketSubscription = _socket?.listen(
      (List<int> data) {
        final message = String.fromCharCodes(data);
        // 添加数据有效性检查
        logger.addLineToChannel(getUniqueKey(), '[RECEIVED]---> $message');
        if (message.isNotEmpty && !dataStream.isClosed) {
          try {
            dataStream.add(message);
          } catch (e) {
            logger.addLineToChannel(getUniqueKey(), 'Error adding data to stream: $e');
          }
        }
      },
      onDone: () {
        logger.addLineToChannel(getUniqueKey(), 'Connection closed by server');
        _startReconnecting();
      },
      onError: (Object error, StackTrace? stackTrace) { // 修改这里
        logger.addLineToChannel(getUniqueKey(), 'Error receiving data: error:$error stackTrace:${stackTrace}');
        _startReconnecting();
      },
    );
  }

  /// 开始重连
  void _startReconnecting() {
    logger.addLineToChannel(getUniqueKey(), 'Reconnect start... _isReconnecting=$_isReconnecting');
    if (!_isReconnecting) {
      connectionStateStream.add(false);
      _isReconnecting = true;
      // 避免创建多个定时器
      _reconnectTimer?.cancel();
      _reconnectTimer ??= Timer.periodic(_reconnectInterval, (timer) async {
        logger.addLineToChannel(getUniqueKey(), 'Reconnect  _reconnectTimer=${_reconnectTimer?.hashCode}');
        await connect();
      });
    }
  }

  /// 发送数据到服务器
  void sendData(Map<String, dynamic> data) {
    final String jsonString = jsonEncode(data);
    logger.addLineToChannel(getUniqueKey(), '[SEND]---> $jsonString');
    if (_socket == null) {
      logger.addLineToChannel(getUniqueKey(), 'Error sending data: Socket is null');
      return;
    }
    try {
      _socket?.add(utf8.encode('$jsonString\n'));
    } catch (e) {
      logger.addLineToChannel(getUniqueKey(), 'Error sending data: $e');
    }
  }

  /// 发送数据到服务器
  void sendDataString(String data) {
    logger.addLineToChannel(getUniqueKey(), '[SEND]---> $data');
    // 检查连接状态
    if (_socket == null) {
      logger.addLineToChannel(getUniqueKey(), 'Error sending data: Socket is null $data');
      return;
    }
    try {
      _socket?.add(utf8.encode('$data\n'));
    } catch (e) {
      logger.addLineToChannel(getUniqueKey(), 'Error sending data: $e $data');
    }
  }

  /// 销毁
  Future<void> disconnect() async {
    _isReconnecting = true;
    _reconnectTimer?.cancel();
    _reconnectTimer = null;
    _socketSubscription?.cancel();
    _socketSubscription = null;

    try {
      // 1. 先关闭输出流，告知服务器不再发送数据
      _socket?.close();
      await Future<void>.delayed(const Duration(milliseconds: 100)); // 给点时间处理
      // 2. 彻底销毁连接，释放资源
      _socket?.destroy();
      // 3. 等待连接完全关闭
      await _socket?.done;
      logger.addLineToChannel(getUniqueKey(), 'disconnect Socket Success 1');
    } catch (e) {
      logger.addLineToChannel(getUniqueKey(), 'disconnect Socket error: $e');
    } finally {
      _socket = null;
      logger.addLineToChannel(getUniqueKey(), 'disconnect Socket finally 2');
    }

    // 安全关闭流
    if (!dataStream.isClosed) {
      dataStream.close();
    }
    if (!connectionStateStream.isClosed) {
      connectionStateStream.close();
    }
    logger.addLineToChannel(getUniqueKey(), 'disconnect Socket disposed 3');
  }

  ///获取唯一标识
  String getUniqueKey() {
    return '$_host:$_port';
  }

  @override
  String toString() {
    return '[$_host:$_port]';
  }

  ///获取唯一标识
  int getIndexMdc() {
    return _indexMdc;
  }
}
